function Vector(a,b) {
    this.x=a;
    this.y=b
}

Vector.prototype= {
    rotate: function(b) {
        var a=this.x;
        var c=this.y;
        this.x=Math.cos(b)*a-Math.sin(b)*c;
        this.y=Math.sin(b)*a+Math.cos(b)*c;
        return this
    },
    
    mult: function(a) {
        this.x*=a;
        this.y*=a;
        return this
    },
    
    clone: function() {
        return new Vector(this.x,this.y)
    },
    
    length: function() {
        return Math.sqrt(this.x*this.x+this.y*this.y)
    },
    
    subtract: function(a) {
        this.x-=a.x;this.y-=a.y;
        return this
    },
    
    set: function(a,b) {
        this.x=a;
        this.y=b;
        return this
    }
};

function Petal(a,f,b,e,c,d) {
    this.stretchA=a;
    this.stretchB=f;
    this.startAngle=b;
    this.angle=e;
    this.bloom=d;
    this.growFactor=c;
    this.r=1;
    this.isfinished=false
}

Petal.prototype= {
    draw: function() {
        var a=this.bloom.garden.ctx;
        var e,d,c,b;
        
        e=new Vector(0,this.r).rotate(Garden.degrad(this.startAngle));
        d=e.clone().rotate(Garden.degrad(this.angle));
        c=e.clone().mult(this.stretchA);
        b=d.clone().mult(this.stretchB);
        a.strokeStyle=this.bloom.c;
        a.beginPath();
        a.moveTo(e.x,e.y);
        a.bezierCurveTo(c.x,c.y,b.x,b.y,d.x,d.y);
        a.stroke()
    },
    
    render:function() {
        if(this.r<=this.bloom.r) {
            this.r+=this.growFactor;
            this.draw()
        } else {
            this.isfinished=true
        }
    }
};

function Bloom(e,d,f,a,b) {
    this.p=e;
    this.r=d;
    this.c=f;
    this.pc=a;
    this.petals=[];
    this.garden=b;
    this.init();
    this.garden.addBloom(this)
}

Bloom.prototype= {
    draw: function() {
        var c,b=true;
        this.garden.ctx.save();
        this.garden.ctx.translate(this.p.x,this.p.y);
        for(var a=0;a<this.petals.length;a++) {
            c=this.petals[a];
            c.render();
            b*=c.isfinished
        }
        
        this.garden.ctx.restore();
        if(b==true) {
            this.garden.removeBloom(this)
        }
    },
    
    init:function() {
        var c=360/this.pc;
        var b=Garden.randomInt(0,90);

        for(var a=0;a<this.pc;a++) {
            var p1 = Garden.random(Garden.options.petalStretch.min,Garden.options.petalStretch.max);
            var p2 = Garden.random(Garden.options.petalStretch.min,Garden.options.petalStretch.max);
            var p3 = b+a*c;
            var p4 = c;
            var p5 = Garden.random(Garden.options.growFactor.min,Garden.options.growFactor.max);

            this.petals.push(new Petal(p1,p2,p3,p4,p5,this))
        }
    }
};

function Garden(a,b) {
    this.blooms = [];
    this.element = b;
    this.ctx = a
}

Garden.prototype= {
    render: function() {
        for(var a = 0; a < this.blooms.length; a++) {
            this.blooms[a].draw()
        }
    },
    
    addBloom: function(a) {
        this.blooms.push(a)
    },
    
    removeBloom:function(a) {
        var d;
        for(var c = 0; c < this.blooms.length; c++) {
            d=this.blooms[c];
            if(d === a) {
                this.blooms.splice(c,1);
                return this
            }
        }
    },
    
    createRandomBloom: function(a, b) {
        var p1 = a;
        var p2 = b;
        var p3 = Garden.randomInt(Garden.options.bloomRadius.min,Garden.options.bloomRadius.max);
        var p4 = Garden.randomrgba(Garden.options.color.rmin,Garden.options.color.rmax,Garden.options.color.gmin,Garden.options.color.gmax,Garden.options.color.bmin,Garden.options.color.bmax,Garden.options.color.opacity);
        var p5 = Garden.randomInt(Garden.options.petalCount.min,Garden.options.petalCount.max);
        
        this.createBloom(p1,p2,p3,p4,p5)
    },
    
    createBloom: function(a, f, d, e, b) {
        new Bloom(new Vector(a, f), d, e, b, this)
    },
    
    clear: function() {
        this.blooms = [];
        this.ctx.clearRect(0, 0, this.element.width, this.element.height)
    }
};

Garden.options= {
    petalCount: {
        min: 8, 
        max:15
    },
    
    petalStretch: {
        min: 0.1,
        max: 3
    },
    
    growFactor: {
        min: 0.1,
        max: 1
    },
    
    bloomRadius: {
        min: 8,
        max: 10
    },
    
    density: 10,
    
    growSpeed: 1000/60,

    color: {
        rmin: 128,
        rmax: 255,
        gmin: 0,
        gmax: 128,
        bmin: 0,
        bmax: 128,
        opacity: 0.1
    },
    
    tanAngle: 60
};

Garden.random=function(b,a) {
    return Math.random()*(a-b)+b
};

Garden.randomInt=function(b,a) {
    return Math.floor(Math.random()*(a-b+1))+b
};

Garden.circle=2*Math.PI;

Garden.degrad=function(a) {
    return Garden.circle/360*a
};

Garden.raddeg=function(a) {
    return a/Garden.circle*360
};

Garden.rgba=function(f,e,c,d) {
    return"rgba("+f+","+e+","+c+","+d+")"
};

Garden.randomrgba=function(i,n,h,m,l,d,k) {
    var c=Math.round(Garden.random(i,n));
    var f=Math.round(Garden.random(h,m));
    var j=Math.round(Garden.random(l,d));
    var e=5;
    
    if(Math.abs(c-f)<=e&&Math.abs(f-j)<=e&&Math.abs(j-c)<=e) {
        return Garden.rgba(i,n,h,m,l,d,k)
    } else {
        return Garden.rgba(c,f,j,k)
    }
};

